#####################################################################
# File:         Toolbar.py
# Product:      KnowledgeEngine
#
# Copyright:    Copyright (c) 2002, Faulkner Technologies.
# Author:       Brian Oliver
#
# Description:  This file defines the Toolbar class, a simple
#               Element that may be used to define toolbars for
#               KE pages, including SimpleReports and Models.  
#               
#               Perhaps in the future other pages, like the user
#               admin will use instances of this class to manage 
#               their tools.
#
# See Also:     Element
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.KnowledgeEngineCore import *
from Products.KnowledgeEngine.ElementContainer import ElementContainer, ElementContainerInfo
from Products.KnowledgeEngine.PropertyDefinition import PropertyDefinition
from Products.KnowledgeEngine.PropertyFormats import pf_TEXT_SINGLELINE

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## ToolbarInfo Class Definition
class ToolbarInfo(ElementContainerInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return "Toolbar"

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "Toolbar"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "toolbar"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('icon.gif', globals())
        
    #---------------------------------------------------------------#

    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):
        """
            ABSTRACT: Returns if class instances (instance) is permitted in 
            the specified container (containerInstance)
            
            NOTE: This is from this class' instance perspective.
        """
        
        #DEFAULT RULE: Toolbars are permitted in any GenericContainer while the container isn't a Component and there isn't already a toolbar in the container
        return containerClassInfo.isInstanceOf('GenericContainer') and (not containerClassInfo.isInstanceOf('Component')) and ((containerInstance != None and len(containerInstance.getChildrenByInstanceOf("Toolbar")) == 0) or containerInstance == None)

    #---------------------------------------------------------------#

    def isChildPermitted(self, childClassInfo, childInstance = None):
        """
            Returns if the specified child is permitted as a 
            child of the class' instances.
            
            NOTE: This is from this class' instance perspective.
            
            For component containers, this always overrides what the
            return value from childClassInfo.isPermittedInContainer(...)
        """
        
        #DEFAULT RULE: Toolbars may have ToolbarTools as children
        return childClassInfo.isInstanceOf('ToolbarTool')
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        ElementContainerInfo.onConfigureProperties(self)
      
        #add the standard 'backgroundColor' property        
        self.addPropertyDefinition(PropertyDefinition(identity="backgroundColor", displayName="Background Color", description="The HTML color constant for the background. (leave empty for transparent)", propertyFormat=pf_TEXT_SINGLELINE, defaultValue=""))

        #add the standard 'backgroundImage' property        
        self.addPropertyDefinition(PropertyDefinition(identity="backgroundImage", displayName="Background Image", description="The URL to the background image for the toolbar. (leave empty for transparent)", propertyFormat=pf_TEXT_SINGLELINE, defaultValue=""))

    #---------------------------------------------------------------#

#####################################################################
## Toolbar Class Definition
class Toolbar(ElementContainer):
    """
        A class to represent a toolbar
    """

    #---------------------------------------------------------------#

    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = ToolbarInfo()

    #---------------------------------------------------------------#

    # Custom zope manage_preview to permit previews of components.
    preview_html = DTMLFile('index_html', globals())

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the Toolbar"        

        ElementContainer.__init__(self, id, identity)
        
        self.backgroundColor = ""
        self.backgroundImage = ""
        
        #perform onAfterInstanciation processing
        self.onAfterInstanciation()

    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """        
        
        #perform default processing
        ElementContainer.onAfterInstanciation(self)
                
    #---------------------------------------------------------------#

    def isDisplayedBeforeComponents(self):
        """
            Returns if the Element is to be displayed before
            components in a model. Alternatively the Element is
            displayed after the components in a model.
            (If the element is in a model)
        """
        
        #Toolbars are displayed before 
        return true

    #---------------------------------------------------------------#

    def getTools(self):
        """
            Returns a sequence of the tools (ToolbarTool)
            in this container, sorted by the ToolbarTool.getOrder()
        """

        #get the immediate children of the container
        children = self.objectValues()

        #filter the Tool(s) only
        tools = [x for x in children if x.isInstanceOf("ToolbarTool")]
        
        #sort the component by ToolbarElement.getOrder()
        tools.sort(lambda x, y : -(x.getOrder() < y.getOrder()))

        return tools                    
        
    #---------------------------------------------------------------#

    def getContent(self, contentZone, forGenericObject = None, componentContext = None, assessment = None):
        """
            Return the Element generated 
            content for the specified contentZone (a string).   

            This method is called by the Model.index_html dtml file
            to customise the appearance of the output.
            
            By overriding this method, Elements have the opportunity
            to perform customization of the output from a Model
            during the assessment process.
        """
        
        #the result for the content zone
        result = ""

        #generate the toolbar?
        if contentZone == "TOOLBAR_TOP" or contentZone == "TOOLBAR_BOTTOM":
            
            #get the tools sorted in display order
            tools = self.getTools()

            #are there any tools?
            if len(tools) > 0:
                #get the alignment of the first tool
                alignment = tools[0].getAlignment()

                #first tool!
                isFirstTool = true

                #the number of columns generated
                nrColumns = 0

                #output the tools
                for tool in tools:
                    
                    #is this the first tool?
                    if isFirstTool:
                        result += '<td align="%s">' % (tool.getAlignment(),)
                        isFirstTool = false
                        nrColumns += 1
                        
                    #is the current alignment different from the last tool?                        
                    elif alignment != tool.getAlignment():
                            result += '</td><td align="%s">' % (tool.getAlignment(),)
                            alignment = tool.getAlignment()
                            nrColumns += 1
            
                    else:
                        result += '&nbsp;'
                                                
                    #output the tool
                    result += tool.getContent(contentZone, forGenericObject, componentContext, assessment)
                    
                #put the html toolbar together
                line = '<tr><td colspan="2" height="1" bgcolor="#FF9E01" nowrap><spacer type="block" width="5"></td></tr>'                

                toolbar = '<table class="keToolbar" width="100%" cellspacing="0" cellpadding="0">'
                
                toolbar += '<tr>' + result + '</td></tr>'                 

                toolbar += '</table> '

                result = toolbar

        #generate the <head> tag
        elif contentZone == "HTML_HEADER":
        
            #add the HTML_HEADER code for each tool in the toolbar
            for tool in self.getTools():
                result += tool.getContent(contentZone, forGenericObject, componentContext, assessment)

        #generate the any other content required
        else:      
            #add the contentZone code for each tool in the toolbar
            for tool in self.getTools():
                result += tool.getContent(contentZone, forGenericObject, componentContext, assessment)
            
        return result
        
    #---------------------------------------------------------------#

    def isInModel(self):
        """
            Return if the toolbar is in a model
        """
        
        return self.getParentByInstanceOf("Model") != None and not self.isInReport()
        
    #---------------------------------------------------------------#

    def isInReport(self):
        """
            Return if the toolbar is in a report
        """
        
        return self.getParentByInstanceOf("Report") != None
        
    #---------------------------------------------------------------#

    def isPreviewPermitted(self):
        """
            Return if the Element is allowed to be previewed.
            
            By default all elements can't be previewed, some however
            should can be previewed. eg: HTMLHeaderFooters
        """
        
        return true
            
    #---------------------------------------------------------------#

    def isOrderedContainer(self):
        """
            Return if the children of the object may use ordering.
            
            This is to allow the 'Order' column in the Content
            management tab in Zope            
        """

        return true
        
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation

# Register Class Information with the Knowledge Engine
registerGenericObjectClass(Toolbar)

#####################################################################
